#!/usr/bin/env python3
"""
CSS语法高亮器
支持CSS选择器、属性、值、注释等
"""

from PyQt5.QtCore import QRegExp
from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat, QColor, QFont

class CSSHighlighter(QSyntaxHighlighter):
    """CSS语法高亮器"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.highlighting_rules = []
        self.setup_rules()
    
    def setup_rules(self):
        """设置CSS语法高亮规则"""
        
        # CSS选择器格式 - 蓝色
        selector_format = QTextCharFormat()
        selector_format.setForeground(QColor('#569CD6'))  # 蓝色
        selector_format.setFontWeight(QFont.Bold)
        
        # CSS选择器（标签、类、ID、属性选择器等）
        selector_pattern = QRegExp(r'[^{}]+\s*(?=\{)')
        self.highlighting_rules.append((selector_pattern, selector_format))
        
        # CSS属性名格式 - 橙色
        property_format = QTextCharFormat()
        property_format.setForeground(QColor('#CE9178'))  # 橙色
        
        # CSS属性名
        property_pattern = QRegExp(r'\b[a-zA-Z-]+\s*(?=:)')
        self.highlighting_rules.append((property_pattern, property_format))
        
        # CSS属性值格式 - 绿色
        value_format = QTextCharFormat()
        value_format.setForeground(QColor('#6A8759'))  # 绿色
        
        # CSS属性值
        value_pattern = QRegExp(r':\s*[^;]+;')
        self.highlighting_rules.append((value_pattern, value_format))
        
        # CSS注释格式 - 灰色
        comment_format = QTextCharFormat()
        comment_format.setForeground(QColor('#808080'))  # 灰色
        comment_format.setFontItalic(True)
        
        # CSS注释
        comment_pattern = QRegExp(r'/\*[^*]*\*+(?:[^/*][^*]*\*+)*/')
        self.highlighting_rules.append((comment_pattern, comment_format))
        
        # CSS关键字格式 - 紫色
        keyword_format = QTextCharFormat()
        keyword_format.setForeground(QColor('#B5CEA8'))  # 紫色
        keyword_format.setFontWeight(QFont.Bold)
        
        # CSS关键字
        css_keywords = [
            'important', 'inherit', 'initial', 'unset', 'auto', 'none', 'normal',
            'bold', 'italic', 'underline', 'overline', 'line-through', 'blink',
            'left', 'right', 'center', 'justify', 'top', 'bottom', 'middle',
            'block', 'inline', 'inline-block', 'flex', 'grid', 'table',
            'relative', 'absolute', 'fixed', 'sticky', 'static',
            'hidden', 'visible', 'collapse', 'separate',
            'solid', 'dashed', 'dotted', 'double', 'groove', 'ridge', 'inset', 'outset',
            'repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round',
            'cover', 'contain', 'fixed', 'local', 'scroll',
            'pointer', 'default', 'text', 'wait', 'help', 'progress',
            'ease', 'linear', 'ease-in', 'ease-out', 'ease-in-out',
            'forwards', 'backwards', 'both', 'infinite', 'alternate',
            'row', 'column', 'wrap', 'nowrap', 'wrap-reverse',
            'start', 'end', 'stretch', 'baseline',
            'screen', 'print', 'speech', 'all'
        ]
        
        for keyword in css_keywords:
            pattern = QRegExp(r'\b' + keyword + r'\b')
            self.highlighting_rules.append((pattern, keyword_format))
        
        # CSS单位格式 - 浅蓝色
        unit_format = QTextCharFormat()
        unit_format.setForeground(QColor('#9CDCFE'))  # 浅蓝色
        
        # CSS单位
        units = ['px', 'em', 'rem', '%', 'vh', 'vw', 'vmin', 'vmax', 'pt', 'pc', 'in', 'cm', 'mm']
        for unit in units:
            pattern = QRegExp(r'\b\d+' + unit + r'\b')
            self.highlighting_rules.append((pattern, unit_format))
        
        # CSS颜色值格式 - 粉色
        color_format = QTextCharFormat()
        color_format.setForeground(QColor('#CE9178'))  # 粉色
        
        # CSS颜色值（十六进制、rgb、rgba、颜色名）
        color_patterns = [
            QRegExp(r'#[0-9a-fA-F]{3,8}\b'),  # 十六进制颜色
            QRegExp(r'rgb\s*\([^)]+\)'),     # rgb颜色
            QRegExp(r'rgba\s*\([^)]+\)'),    # rgba颜色
            QRegExp(r'hsl\s*\([^)]+\)'),     # hsl颜色
            QRegExp(r'hsla\s*\([^)]+\)')     # hsla颜色
        ]
        
        for pattern in color_patterns:
            self.highlighting_rules.append((pattern, color_format))
        
        # 颜色名称格式 - 浅绿色
        color_name_format = QTextCharFormat()
        color_name_format.setForeground(QColor('#B5CEA8'))  # 浅绿色
        
        # CSS颜色名称
        color_names = [
            'red', 'green', 'blue', 'yellow', 'orange', 'purple', 'pink', 'brown',
            'black', 'white', 'gray', 'silver', 'gold', 'cyan', 'magenta', 'lime',
            'maroon', 'olive', 'teal', 'navy', 'aqua', 'fuchsia', 'coral',
            'indigo', 'violet', 'turquoise', 'salmon', 'tan', 'beige', 'ivory'
        ]
        
        for color in color_names:
            pattern = QRegExp(r'\b' + color + r'\b')
            self.highlighting_rules.append((pattern, color_name_format))
        
        # CSS函数格式 - 青色
        function_format = QTextCharFormat()
        function_format.setForeground(QColor('#4EC9B0'))  # 青色
        
        # CSS函数
        css_functions = [
            'url', 'calc', 'var', 'linear-gradient', 'radial-gradient',
            'conic-gradient', 'repeating-linear-gradient', 'repeating-radial-gradient',
            'min', 'max', 'clamp', 'attr', 'counter', 'counters', 'scale',
            'rotate', 'translate', 'skew', 'matrix', 'perspective'
        ]
        
        for func in css_functions:
            pattern = QRegExp(r'\b' + func + r'\s*\(')
            self.highlighting_rules.append((pattern, function_format))
        
        # CSS伪类和伪元素格式 - 橙色
        pseudo_format = QTextCharFormat()
        pseudo_format.setForeground(QColor('#CE9178'))  # 橙色
        pseudo_format.setFontWeight(QFont.Bold)
        
        # CSS伪类和伪元素
        pseudo_elements = [
            'hover', 'active', 'focus', 'visited', 'link', 'target',
            'first-child', 'last-child', 'nth-child', 'nth-of-type',
            'before', 'after', 'first-letter', 'first-line', 'selection',
            'placeholder', 'checked', 'disabled', 'enabled', 'required',
            'valid', 'invalid', 'in-range', 'out-of-range', 'read-only',
            'read-write', 'optional', 'default', 'root', 'empty', 'not'
        ]
        
        for pseudo in pseudo_elements:
            pattern = QRegExp(r':' + pseudo + r'\b')
            self.highlighting_rules.append((pattern, pseudo_format))
        
        # CSS媒体查询格式 - 紫色
        media_format = QTextCharFormat()
        media_format.setForeground(QColor('#B5CEA8'))  # 紫色
        media_format.setFontWeight(QFont.Bold)
        
        # CSS媒体查询
        media_keywords = ['media', 'screen', 'print', 'speech', 'all', 'only', 'not', 'and', 'or']
        for keyword in media_keywords:
            pattern = QRegExp(r'@' + keyword + r'\b')
            self.highlighting_rules.append((pattern, media_format))
        
        # 数字格式 - 浅黄色
        number_format = QTextCharFormat()
        number_format.setForeground(QColor('#DCDCAA'))  # 浅黄色
        
        # 数字
        number_pattern = QRegExp(r'\b\d+\.?\d*\b')
        self.highlighting_rules.append((number_pattern, number_format))
    
    def highlightBlock(self, text):
        """高亮文本块"""
        # 先处理多行注释（需要特殊处理）
        self.highlight_multiline_comments(text)
        
        # 然后处理其他规则
        for pattern, format_ in self.highlighting_rules:
            expression = QRegExp(pattern)
            index = expression.indexIn(text)
            while index >= 0:
                length = expression.matchedLength()
                # 检查是否已经在注释中
                if self.currentBlockState() != 1:
                    self.setFormat(index, length, format_)
                index = expression.indexIn(text, index + length)
    
    def highlight_multiline_comments(self, text):
        """处理多行注释高亮"""
        # 获取前一个块的状态
        previous_state = self.previousBlockState()
        
        # 注释格式
        comment_format = QTextCharFormat()
        comment_format.setForeground(QColor('#808080'))  # 灰色
        comment_format.setFontItalic(True)
        
        start_index = 0
        
        # 如果前一个块在注释中，继续高亮
        if previous_state == 1:
            start_index = 0
            self.setFormat(0, len(text), comment_format)
            
            # 查找注释结束位置
            end_pattern = QRegExp(r'\*/')
            end_index = end_pattern.indexIn(text)
            if end_index >= 0:
                # 注释结束，重置状态
                self.setCurrentBlockState(0)
            else:
                # 注释继续到下一行
                self.setCurrentBlockState(1)
            return
        
        # 查找注释开始
        start_pattern = QRegExp(r'/\*')
        start_index = start_pattern.indexIn(text)
        
        while start_index >= 0:
            # 查找注释结束
            end_pattern = QRegExp(r'\*/')
            end_index = end_pattern.indexIn(text, start_index + 2)
            
            if end_index == -1:
                # 注释跨越多行
                self.setFormat(start_index, len(text) - start_index, comment_format)
                self.setCurrentBlockState(1)
                break
            else:
                # 单行内的注释
                self.setFormat(start_index, end_index - start_index + 2, comment_format)
                start_index = end_pattern.indexIn(text, end_index + 2)